package com.ysyx.ysyx_roborder.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysyx.ysyx_roborder.dto.BaseDto;
import com.ysyx.ysyx_roborder.pojo.OrderPojo;
import com.ysyx.ysyx_roborder.qo.OrderQo;
import com.ysyx.ysyx_roborder.qo.TakeOrderQo;
import com.ysyx.ysyx_roborder.service.OrderPojoService;
import com.ysyx.ysyx_roborder.mapper.OrderPojoMapper;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.GeoPosition;
import org.redisson.api.RGeo;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* @author 薛宇晖
* @description 针对表【order_inf(订单表)】的数据库操作Service实现
* @createDate 2023-04-10 19:05:00
*/
@Service
public class OrderPojoServiceImpl
    implements OrderPojoService{

    @Autowired
    private OrderPojoMapper orderPojoMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public int updateOrderStatus(OrderPojo orderPojo) {

//        QueryWrapper queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("order_id",orderPojo.getOrderId());
        return  orderPojoMapper.updateById(orderPojo);



    }

    @Override
    public BaseDto driver(OrderQo qo) {
        //获取 订单编号和司机编号
//        qo.setOrderId("fz00001");
//        qo.setDriverId(1);
        BaseDto baseDto = new BaseDto();
        //去尝试移动司机出 上工司机待命池   work:driver:driverId  ==> working:driver set
        boolean delUnwork = redissonClient.getBucket("work:driver:" + qo.getDriverId()).delete();
        if (!delUnwork) {
            baseDto = new BaseDto(101,"司机已经在行程中或未上工",null);
            return baseDto;
        }
        //添加到工作中司机池  防止司机同时接两单
        boolean addWorking = redissonClient.getSet("working:driver").add(qo.getDriverId());
        if (!addWorking) {
            baseDto = new BaseDto(101,"司机已经在工作了",null);
            return baseDto;
        }

        //尝试删除
        boolean delUnorder = redissonClient.getBucket("pend:order:" + qo.getOrderId()).delete();
        if (!delUnorder) {
            baseDto = new BaseDto(103,"订单已被其他司机接取",null);
            return baseDto;
        }

        //添加到行程中订单池
        boolean tense = redissonClient.getSet("tense:order").add(qo.getOrderId());
        if (!tense) {
            baseDto = new BaseDto(103,"订单已被其他司机接取",null);
            return baseDto;
        }

        //修改订单状态 改为 301 行程中
        RMap<Object, Object> map = redissonClient.getMap("orderinfo:" + qo.getOrderId());
        RMap<Object, Object> map3 = redissonClient.getMap("driverinfo:" + qo.getDriverId());

        map.put("orderStatus",301);
        map.put("driverId",qo.getDriverId());
        map.put("driverTel",map3.get("driverTel"));

//        TransactionOptions options = TransactionOptions.defaults();  事务 但不适用高并发
//        for (Object k : map.keySet()) {
//            System.out.println(k+"-----"+map.get(k));
//        }

        //返回数据给前端  答辩RMap
        try {
            List<TakeOrderQo> pojos = new ArrayList<>();

            TakeOrderQo o = new TakeOrderQo();
            o.setOrderId((String) map.get("orderId"));
            o.setPassengerId(Integer.valueOf((String) map.get("passengerId")));
            o.setOrderStatus(Integer.valueOf((String) map.get("orderStatus")));
            o.setOrderCost((Double.parseDouble((String) map.get("orderCost"))));
            o.setOrderMileage((Double.parseDouble((String) map.get("orderMileage"))) );
            o.setDriverId((Integer.valueOf((String) map.get("driverId"))));
            o.setStartName((String) map.get("startName"));
            o.setEndName((String) map.get("endName"));
            o.setStartLongitude(Double.parseDouble((String) map.get("startLongitude")) );
            o.setStartLatitude(Double.parseDouble((String) map.get("startLatitude")) );
            o.setEndLongitude(Double.parseDouble((String) map.get("endLongitude")) );
            o.setEndLatitude(Double.parseDouble((String) map.get("endLatitude")) );

            RMap<Object, Object> map2 = redissonClient.getMap("driverinfo:" + qo.getDriverId());

            o.setDriverTel((String) map2.get("driverTel"));
            o.setPassengerTel((String) map.get("passengerTel"));
//            (Date) orderMap.get("orderStatustime")
//            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-01-03 10:59:27")

            o.setOrderStatustime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String)map.get("orderStatustime")));
            o.setOrderStatus((Integer.valueOf((String) map.get("orderStatus"))));

            //顺便删除桶里面的鬼屎
            List<RMap<Object,Object>> maps = new ArrayList<>();
            RMap<Object, Object> mapA1 = redissonClient.getMap("area:A1");
            RMap<Object, Object> mapA2 = redissonClient.getMap("area:A2");
            RMap<Object, Object> mapA3 = redissonClient.getMap("area:A3");
            RMap<Object, Object> mapB1 = redissonClient.getMap("area:B1");
            RMap<Object, Object> mapB2 = redissonClient.getMap("area:B2");
            RMap<Object, Object> mapB3 = redissonClient.getMap("area:B3");
            maps.add(mapA1);
            maps.add(mapA2);
            maps.add(mapA3);
            maps.add(mapB1);
            maps.add(mapB2);
            maps.add(mapB3);

            String theArea = "";
            //判断司机的位置
            for (RMap<Object, Object> map1 : maps) {

                theArea = map1.getName();
                //每个地区池子去判断之前的地理信息
                boolean remove = redissonClient.getGeo(theArea + ":orders").remove(qo.getOrderId());

                if (remove==true) {
                    break;
                }

            }

            RGeo<String> geo = redissonClient.getGeo("order:track:" + qo.getOrderId());
            System.out.println("area:" + theArea);
            RGeo<Object> geo1 = redissonClient.getGeo(theArea + ":drivers");
            Map<Object, GeoPosition> pos = geo1.pos(qo.getDriverId());
            GeoPosition geoPosition = pos.get(qo.getDriverId());
            System.err.println(geoPosition);
            geo.add(geoPosition.getLongitude(),geoPosition.getLatitude(),String.valueOf(new Date().getTime()));

            o.setDriverLongitude(geoPosition.getLongitude());
            o.setDriverLatitude(geoPosition.getLatitude());
            pojos.add(o);

            System.err.println(o);

            baseDto = new BaseDto(201,"成功抢到，请快去接送乘客",pojos);

            //我在这写Mq
//            rocketMQTemplate.convertAndSend("order:gainset", JSON.toJSONString(o));
            OrderPojo orderPojo = new OrderPojo();
            orderPojo.setOrderId(o.getOrderId());
            orderPojo.setOrderStatus(o.getOrderStatus());
            orderPojo.setDriverId(o.getDriverId());
            orderPojo.setPassengerId(o.getPassengerId());
            orderPojo.setOrderCost(o.getOrderCost());
            orderPojo.setOrderMileage(o.getOrderMileage());
            orderPojo.setEndName(o.getEndName());
            orderPojo.setStartName(o.getStartName());
            orderPojo.setOrderStatustime(o.getOrderStatustime());
            orderPojoMapper.updateById(orderPojo);
            redissonClient.getGeo(theArea+":drivers").remove(qo.getDriverId());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return baseDto;
    }
}




